package cn.com.cis.utils.tree;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import cn.com.cis.domain.Privilege;
import cn.com.cis.domain.Role;
import cn.com.cis.domain.User;
import cn.com.cis.service.PrivilegeService;
import cn.com.cis.service.RoleService;
import cn.com.cis.service.UserService;

public class PrivilegeTreeConstructor {
	
	TreeManager treeManager = new TreeManager();
	
	private PrivilegeService privilegeService;
	
	public void setPrivilegeService(PrivilegeService privilegeService) {
		this.privilegeService = privilegeService;
	}
	
	public String getPrivilegeTreeString() {
		List<String> allPrivileges = new ArrayList<String>();
		for(Privilege aPrivilege : privilegeService.selectPrivileges()){
			allPrivileges.add(aPrivilege.getCode());
		}
		
		List<TreeNode> trees = treeManager.plainTextToTree(allPrivileges);
		
		String jsObjectString = "[";
		for(TreeNode tree : trees){
			jsObjectString += toJsObjectStructure(tree) + ",";
		}
		jsObjectString += "]";
		
		return jsObjectString;
	}

	private String toJsObjectStructure(TreeNode node) {
		String objectString = "{";
		objectString += "text: '" + node.getNodeName() + "',";
		
		if(!node.isLeaf()){ // 非叶子节点，说明存在子节点，遍历查出 
			objectString += "nodes: [";
			
			for(TreeNode childNode : node.getChildrenNodes()){
				objectString += toJsObjectStructure(childNode) + ",";
			}
			
			// int childrenNum = node.getChildrenNodes().size();
			
			objectString += "],";
			objectString += "selectable: false,";
			// objectString += "tags: ['" + childrenNum + "'],";
		} else {   // 叶子节点，make it checkable
			objectString += "icon: 'glyphicon glyphicon-unchecked',selectedIcon: 'glyphicon glyphicon-check',";
			objectString += getLeafProperty(node);    // 获取已赋权节点初始状态
			objectString += "permissionCode: '" + treeManager.getNodePermissionCode(node) + "'";  // js节点自带权限信息，方便事件获取
		}
		
		objectString += "}";
		
		return objectString;
	}
	
	private UserService userService;
	
	private RoleService roleService;
	
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public void setRoleService(RoleService roleService) {
		this.roleService = roleService;
	}

	private User user;
	private List<Role> userRoles;
	private Set<String> userRolePermissions;
	private boolean isAdmin;
	
	private Role role;
	
	private boolean setPermissionsForRole = true; // true: 当前正在为角色设置权限， false: 当前正在为用户设置权限
	
	public void isSetPermissionsForRole(boolean setPermissionsForRole) {
		this.setPermissionsForRole = setPermissionsForRole;
	}

	private String getLeafProperty(TreeNode node) {
		
		// 初始状态下，未选择用户和角色
		if(null == user && null == role){
			return "";
		}
		
		if(setPermissionsForRole){
			if(isRoleHaveThisPermission(node)){
				return "state: { selected: true },";
			}
		} else {
			
			setRolesForUser(user);
			
			if(isUserRolesHaveThisPermission(node)){
				return "state: { selected: true, disabled: true},";
			} else if(isUserHaveThisPermission(node)){
				return "state: { selected: true},";
			}
		}
		
		return "";
	}
	
	private void setRolesForUser(User user) {
		userRoles = roleService.selectRolesByUserId(user.getId());
		for(Role role: userRoles){
			if("admin".equals(role.getRoleName())){
				isAdmin = true;
			}
		}
	}
	
	private boolean isUserRolesHaveThisPermission(TreeNode node){
		
		if(isAdmin){
			return true;
		}
		
		if(null == userRolePermissions){
			userRolePermissions = new HashSet<String>();
			for(Role role : userRoles){
				for(String permission : roleService.selectPermissionsForRole(role.getRoleId())){
					userRolePermissions.add(permission);
				}
			}
		}
		
		return userRolePermissions.contains(TreeManager.getNodeFullName(node));
	}

	private boolean isRoleHaveThisPermission(TreeNode node) {
		
		if(null == role){
			return false;                       
		}
		
		if("admin".equals(role.getRoleName())){   // 最高权限角色直接返回
			return true;
		}
		
		Set<String> permissions = new HashSet<String>();
		for(String permission : roleService.selectPermissionsForRole(role.getRoleId())){ 
			permissions.add(permission);
		}
		
		return permissions.contains(TreeManager.getNodeFullName(node));
	}
	
	private boolean isUserHaveThisPermission(TreeNode node) {
		
		Set<String> permissions = new HashSet<String>();
		for(String permission : userService.selectPermissionsForUser(user.getId())){  
			permissions.add(permission);
		}
		
		return permissions.contains(TreeManager.getNodeFullName(node));
	}

	public void setUser(User user) {
		this.user = user;
	}

	public void setRole(Role role) {
		this.role = role;
	}
	
	public List<TreeNode> getPermissionArray(){
		
		List<String> allPrivileges = new ArrayList<String>();
		for(Privilege aPrivilege : privilegeService.selectPrivileges()){
			allPrivileges.add(aPrivilege.getCode());
		}
		
		List<TreeNode> array = new ArrayList<TreeNode>();
		List<TreeNode> trees = treeManager.plainTextToTree(allPrivileges);
		for(TreeNode tree : trees){
			array.addAll(LeafAndParent(tree));
		}
		
		return null;
	}

	private List<TreeNode> LeafAndParent(TreeNode tree) {
		
		List<TreeNode> array = new ArrayList<TreeNode>();
		if(tree.isLeaf() || tree.containsLeafNode()){
			array.add(tree);
		}
		
		if(!tree.isLeaf()){
			for(TreeNode child : tree.getChildrenNodes()){
				array.addAll(LeafAndParent(child));
			}
		}
		
		return array;
	}

}
